home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-04-03 | 32.2 KB | 1,084 lines | [TEXT/MPS ] |
- //----------------------------------------------------------------------------------------
- // UBusyCursor.cp
- // Copyright © 1985-96 by Apple Computer, Inc. All rights reserved.
- //----------------------------------------------------------------------------------------
-
- #ifndef __UBUSYCURSOR__
- #include "UBusyCursor.h"
- #endif
-
- // MacApp
-
- #ifndef __UCOREUTILITIES__
- #include "UCoreUtilities.h"
- #endif
-
- #ifndef __UFAILURE__
- #include "UFailure.h"
- #endif
-
- #ifndef __UMEMORY__
- #include "UMemory.h"
- #endif
-
- #ifndef __UPATCH__
- #include "UPatch.h"
- #endif
-
- // Toolbox
-
- #ifndef __LOWMEM__
- #include <LowMem.h>
- #endif
-
- #ifndef __RESOURCES__
- #include <Resources.h>
- #endif
-
- #ifndef __TOOLUTILS__
- #include <ToolUtils.h>
- #endif
-
- #ifndef __TRAPS__
- #include <Traps.h>
- #endif
-
- //----------------------------------------------------------------------------------------
-
- #ifndef qPatchEventAvail
- #define qPatchEventAvail 0
- #endif
-
- //----------------------------------------------------------------------------------------
- const ResNumber kAcurRsrcID = 256;
-
- //----------------------------------------------------------------------------------------
- // static data members
- //----------------------------------------------------------------------------------------
- TBusyCursor* TBusyCursor::fgBusyCursor;
- Boolean TBusyCursor::pBusyCursorVBLInstalled; // used for proper failure handling
-
- TBusyCursorPtr& gBusyCursor = TBusyCursor::fgBusyCursor;
-
- #if qPatchEventAvail
- //========================================================================================
- // CLASS PatchEventAvail
- //========================================================================================
- #pragma segment MABusyCursorRes
-
- typedef pascal Boolean (*EventAvailType)(short eventMask, EventRecord* theEvent);
-
- #if GENERATINGCFM
- typedef UniversalProcPtr EventAvailUPP;
- #else
- typedef ProcPtr EventAvailUPP;
- #endif
-
- enum
- {
- uppEventAvailProcInfo = kPascalStackBased
- | RESULT_SIZE(SIZE_CODE(sizeof(Boolean)))
- | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(short)))
- | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(EventRecord*)))
- };
-
- #if GENERATINGCFM
- #define NewEventAvailProc(userRoutine) \
- (EventAvailUPP) NewRoutineDescriptor((ProcPtr)(userRoutine), uppEventAvailProcInfo, GetCurrentISA())
- #else
- #define NewEventAvailProc(userRoutine) \
- ((EventAvailUPP) (userRoutine))
- #endif
-
- #if GENERATINGCFM
- #define CallEventAvailProc(userRoutine, eventMask, theEvent) \
- CallUniversalProc((UniversalProcPtr)(userRoutine), uppEventAvailProcInfo, (eventMask), (theEvent))
- #else
- #define CallEventAvailProc(userRoutine, eventMask, theEvent) \
- (*(userRoutine))((eventMask), (theEvent))
- #endif
-
- //========================================================================================
-
- class PatchEventAvail : public TrapPatch
- {
- public:
- void Install(EventAvailType routine);
- Boolean CallInherited(short eventMask, EventRecord* theEvent);
- };
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment MABusyCursorRes
-
- void PatchEventAvail::Install(EventAvailType routine)
- {
- patchRoutine = NewEventAvailProc(StripLong(routine));
- FailNIL(patchRoutine);
- PatchTrap(_EventAvail, patchRoutine);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment MABusyCursorRes
-
- Boolean PatchEventAvail::CallInherited(short eventMask, EventRecord* theEvent)
- {
- return CallEventAvailProc((EventAvailType) oldTrapAddr, eventMask, theEvent);
- }
- #endif // qPatchEventAvail
-
- //========================================================================================
- // CLASS PatchGetNextEvent
- //========================================================================================
- #pragma segment MABusyCursorRes
-
- typedef pascal Boolean (*GetNextEventType)(short eventMask, EventRecord* theEvent);
-
- #if GENERATINGCFM
- typedef UniversalProcPtr GetNextEventUPP;
- #else
- typedef ProcPtr GetNextEventUPP;
- #endif
-
- enum
- {
- uppGetNextEventProcInfo = kPascalStackBased
- | RESULT_SIZE(SIZE_CODE(sizeof(Boolean)))
- | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(short)))
- | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(EventRecord*)))
- };
-
- #if GENERATINGCFM
- #define NewGetNextEventProc(userRoutine) \
- (GetNextEventUPP) NewRoutineDescriptor((ProcPtr)(userRoutine), uppGetNextEventProcInfo, GetCurrentISA())
- #else
- #define NewGetNextEventProc(userRoutine) \
- ((GetNextEventUPP) (userRoutine))
- #endif
-
- #if GENERATINGCFM
- #define CallGetNextEventProc(userRoutine, eventMask, theEvent) \
- CallUniversalProc((UniversalProcPtr)(userRoutine), uppGetNextEventProcInfo, (eventMask), (theEvent))
- #else
- #define CallGetNextEventProc(userRoutine, eventMask, theEvent) \
- (*(userRoutine))((eventMask), (theEvent))
- #endif
-
- class PatchGetNextEvent : public TrapPatch
- {
- public:
- void Install(GetNextEventType routine);
- Boolean CallInherited(short eventMask, EventRecord* theEvent);
- };
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment MABusyCursorRes
-
- void PatchGetNextEvent::Install(GetNextEventType routine)
- {
- patchRoutine = NewGetNextEventProc(StripLong(routine));
- FailNIL(patchRoutine);
- PatchTrap(_GetNextEvent, patchRoutine);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment MABusyCursorRes
-
- Boolean PatchGetNextEvent::CallInherited(short eventMask, EventRecord* theEvent)
- {
- return CallGetNextEventProc((GetNextEventType) oldTrapAddr, eventMask, theEvent);
- }
-
- //========================================================================================
- // CLASS PatchInitCursor
- //========================================================================================
- #pragma segment MABusyCursorRes
-
- typedef pascal void (*InitCursorType)(void);
-
- #if GENERATINGCFM
- typedef UniversalProcPtr InitCursorUPP;
- #else
- typedef ProcPtr InitCursorUPP;
- #endif
-
- enum
- {
- uppInitCursorProcInfo = kPascalStackBased
- };
-
- #if GENERATINGCFM
- #define NewInitCursorProc(userRoutine) \
- (InitCursorUPP) NewRoutineDescriptor((ProcPtr)(userRoutine), uppInitCursorProcInfo, GetCurrentISA())
- #else
- #define NewInitCursorProc(userRoutine) \
- ((InitCursorUPP) (userRoutine))
- #endif
-
- #if GENERATINGCFM
- #define CallInitCursorProc(userRoutine) \
- CallUniversalProc((UniversalProcPtr)(userRoutine), uppInitCursorProcInfo)
- #else
- #define CallInitCursorProc(userRoutine) \
- (*(userRoutine))()
- #endif
-
- class PatchInitCursor : public TrapPatch
- {
- public:
- void Install(InitCursorType routine);
- void CallInherited();
- };
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment MABusyCursorRes
-
- void PatchInitCursor::Install(InitCursorType routine)
- {
- patchRoutine = NewInitCursorProc(StripLong(routine));
- FailNIL(patchRoutine);
- PatchTrap(_InitCursor, patchRoutine);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment MABusyCursorRes
-
- void PatchInitCursor::CallInherited()
- {
- CallInitCursorProc((InitCursorType) oldTrapAddr);
- }
-
- //========================================================================================
- // CLASS PatchSetCCursor
- //========================================================================================
- #pragma segment MABusyCursorRes
-
- typedef pascal void (*SetCCursorType)(CCrsrHandle cCrsr);
-
- #if GENERATINGCFM
- typedef UniversalProcPtr SetCCursorUPP;
- #else
- typedef ProcPtr SetCCursorUPP;
- #endif
-
- enum
- {
- uppSetCCursorProcInfo = kPascalStackBased
- | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(CCrsrHandle)))
- };
-
- #if GENERATINGCFM
- #define NewSetCCursorProc(userRoutine) \
- (SetCCursorUPP) NewRoutineDescriptor((ProcPtr)(userRoutine), uppSetCCursorProcInfo, GetCurrentISA())
- #else
- #define NewSetCCursorProc(userRoutine) \
- ((SetCCursorUPP) (userRoutine))
- #endif
-
- #if GENERATINGCFM
- #define CallSetCCursorProc(userRoutine, cCrsr) \
- CallUniversalProc((UniversalProcPtr)(userRoutine), uppSetCCursorProcInfo, (cCrsr))
- #else
- #define CallSetCCursorProc(userRoutine, cCrsr) \
- (*(userRoutine))((cCrsr))
- #endif
-
- class PatchSetCCursor : public TrapPatch
- {
- public:
- void Install(SetCCursorType routine);
- void CallInherited(CCrsrHandle cCrsr);
- };
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment MABusyCursorRes
-
- void PatchSetCCursor::Install(SetCCursorType routine)
- {
- patchRoutine = NewSetCCursorProc(StripLong(routine));
- FailNIL(patchRoutine);
- PatchTrap(_SetCCursor, patchRoutine);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment MABusyCursorRes
-
- void PatchSetCCursor::CallInherited(CCrsrHandle cCrsr)
- {
- CallSetCCursorProc((SetCCursorType) oldTrapAddr, cCrsr);
- }
-
- //========================================================================================
- // CLASS PatchSetCursor
- //========================================================================================
- #pragma segment MABusyCursorRes
-
- typedef pascal void (*SetCursorType)(const Cursor *crsr);
-
- #if GENERATINGCFM
- typedef UniversalProcPtr SetCursorUPP;
- #else
- typedef ProcPtr SetCursorUPP;
- #endif
-
- enum
- {
- uppSetCursorProcInfo = kPascalStackBased
- | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(Cursor *)))
- };
-
- #if GENERATINGCFM
- #define NewSetCursorProc(userRoutine) \
- (SetCursorUPP) NewRoutineDescriptor((ProcPtr)(userRoutine), uppSetCursorProcInfo, GetCurrentISA())
- #else
- #define NewSetCursorProc(userRoutine) \
- ((SetCursorUPP) (userRoutine))
- #endif
-
- #if GENERATINGCFM
- #define CallSetCursorProc(userRoutine, crsr) \
- CallUniversalProc((UniversalProcPtr)(userRoutine), uppSetCursorProcInfo, (crsr))
- #else
- #define CallSetCursorProc(userRoutine, crsr) \
- (*(userRoutine))(crsr)
- #endif
-
- class PatchSetCursor : public TrapPatch
- {
- public:
- void Install(SetCursorType routine);
- void CallInherited(const Cursor *crsr);
- };
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment MABusyCursorRes
-
- void PatchSetCursor::Install(SetCursorType routine)
- {
- patchRoutine = NewSetCursorProc(StripLong(routine));
- FailNIL(patchRoutine);
- PatchTrap(_SetCursor, patchRoutine);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment MABusyCursorRes
-
- void PatchSetCursor::CallInherited(const Cursor *crsr)
- {
- CallSetCursorProc((SetCursorType) oldTrapAddr, crsr);
- }
-
- //========================================================================================
- // CLASS PatchStillDown
- //========================================================================================
- #pragma segment MABusyCursorRes
-
- typedef pascal Boolean (*StillDownType)();
-
- #if GENERATINGCFM
- typedef UniversalProcPtr StillDownUPP;
- #else
- typedef ProcPtr StillDownUPP;
- #endif
-
- enum
- {
- uppStillDownProcInfo = kPascalStackBased
- | RESULT_SIZE(SIZE_CODE(sizeof(Boolean)))
- };
-
- #if GENERATINGCFM
- #define NewStillDownProc(userRoutine) \
- (StillDownUPP) NewRoutineDescriptor((ProcPtr)(userRoutine), uppStillDownProcInfo, GetCurrentISA())
- #else
- #define NewStillDownProc(userRoutine) \
- ((StillDownUPP) (userRoutine))
- #endif
-
- #if GENERATINGCFM
- #define CallStillDownProc(userRoutine) \
- CallUniversalProc((UniversalProcPtr)(userRoutine), uppStillDownProcInfo)
- #else
- #define CallStillDownProc(userRoutine) \
- (*(userRoutine))()
- #endif
-
- class PatchStillDown : public TrapPatch
- {
- public:
- void Install(StillDownType routine);
- Boolean CallInherited();
- };
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment MABusyCursorRes
-
- void PatchStillDown::Install(StillDownType routine)
- {
- patchRoutine = NewStillDownProc(StripLong(routine));
- FailNIL(patchRoutine);
- PatchTrap(_StillDown, patchRoutine);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment MABusyCursorRes
-
- Boolean PatchStillDown::CallInherited()
- {
- return CallStillDownProc((StillDownType) oldTrapAddr);
- }
-
- //========================================================================================
- // CLASS PatchWaitMouseUp
- //========================================================================================
- #pragma segment MABusyCursorRes
-
- typedef pascal Boolean (*WaitMouseUpType)();
-
- #if GENERATINGCFM
- typedef UniversalProcPtr WaitMouseUpUPP;
- #else
- typedef ProcPtr WaitMouseUpUPP;
- #endif
-
- enum
- {
- uppWaitMouseUpProcInfo = kPascalStackBased
- | RESULT_SIZE(SIZE_CODE(sizeof(Boolean)))
- };
-
- #if GENERATINGCFM
- #define NewWaitMouseUpProc(userRoutine) \
- (WaitMouseUpUPP) NewRoutineDescriptor((ProcPtr)(userRoutine), uppWaitMouseUpProcInfo, GetCurrentISA())
- #else
- #define NewWaitMouseUpProc(userRoutine) \
- ((WaitMouseUpUPP) (userRoutine))
- #endif
-
- #if GENERATINGCFM
- #define CallWaitMouseUpProc(userRoutine) \
- CallUniversalProc((UniversalProcPtr)(userRoutine), uppWaitMouseUpProcInfo)
- #else
- #define CallWaitMouseUpProc(userRoutine) \
- (*(userRoutine))()
- #endif
-
- class PatchWaitMouseUp : public TrapPatch
- {
- public:
- void Install(WaitMouseUpType routine);
- Boolean CallInherited();
- };
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment MABusyCursorRes
-
- void PatchWaitMouseUp::Install(WaitMouseUpType routine)
- {
- patchRoutine = NewWaitMouseUpProc(StripLong(routine));
- FailNIL(patchRoutine);
- PatchTrap(_WaitMouseUp, patchRoutine);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment MABusyCursorRes
-
- Boolean PatchWaitMouseUp::CallInherited()
- {
- return CallWaitMouseUpProc((WaitMouseUpType) oldTrapAddr);
- }
-
- //========================================================================================
-
- #if qPatchEventAvail
- static PatchEventAvail pEAPatch; // patch for EventAvail
- #endif
- static PatchGetNextEvent pGNEPatch; // patch for GetNextEvent
- static PatchInitCursor pICPatch; // patch for InitCursor
- static PatchSetCCursor pSCCPatch; // patch for SetCCursor
- static PatchSetCursor pSCPatch; // patch for SetCursor
- static PatchStillDown pSDPatch; // patch for StillDown under A/UX or PowerPC
- static PatchWaitMouseUp pWMUPatch; // patch for WaitMouseUp under A/UX
-
- //========================================================================================
- // GLOBAL Procedures
- //========================================================================================
- #undef Inherited
-
- #if qPatchEventAvail
- static pascal Boolean ResetBusyEventAvail(short eventMask, EventRecord* theEvent);
- #endif
- static pascal Boolean ResetBusyGetNextEvent(short eventMask, EventRecord* theEvent);
- static pascal Boolean ResetBusyStillDown();
- static pascal Boolean ResetBusyWaitMouseUp();
-
- #if qPowerPC
- static pascal void ABusyTask(VBLTaskPtr vblTaskPtr);
- #else
- static pascal void ABusyTask();
- #endif
-
- //----------------------------------------------------------------------------------------
- // ResetBusyCursor:
- //----------------------------------------------------------------------------------------
- #pragma segment MABusyCursorRes
-
- void TBusyCursor::ResetBusyCursor()
- {
- if (fgBusyCursor && !fgBusyCursor->fIgnoreReset)
- fgBusyCursor->Reset(fgBusyCursor->fBusyDelay);
- } // TBusyCursor::ResetBusyCursor
-
- #if qPatchEventAvail
- pascal Boolean ResetBusyEventAvail(short eventMask, EventRecord* theEvent)
- {
- long OldA5 = SetCurrentA5(); // ***** Called from trap patches *****
-
- TBusyCursor::ResetBusyCursor();
- Boolean avail = pEAPatch.CallInherited(eventMask, theEvent);
-
- SetA5(OldA5);
-
- return avail;
- }
- #endif
-
- pascal Boolean ResetBusyGetNextEvent(short eventMask, EventRecord* theEvent)
- {
- long OldA5 = SetCurrentA5(); // ***** Called from trap patches *****
-
- TBusyCursor::ResetBusyCursor();
- Boolean avail = pGNEPatch.CallInherited(eventMask, theEvent);
-
- SetA5(OldA5);
-
- return avail;
- }
-
- pascal Boolean ResetBusyStillDown()
- {
- long OldA5 = SetCurrentA5(); // ***** Called from trap patches *****
-
- TBusyCursor::ResetBusyCursor();
- Boolean isStillDown = pSDPatch.CallInherited();
-
- SetA5(OldA5);
-
- return isStillDown;
- }
-
- pascal Boolean ResetBusyWaitMouseUp()
- {
- long OldA5 = SetCurrentA5(); // ***** Called from trap patches *****
-
- TBusyCursor::ResetBusyCursor();
- Boolean isStillDown = pWMUPatch.CallInherited();
-
- SetA5(OldA5);
-
- return isStillDown;
- }
-
- //----------------------------------------------------------------------------------------
- // SetCMacAppCursor: Must be in Main segment, and cannot call to any other segment because
- // SetCursor is called from the ABusyTask VBL task. The SetCCursor patch, used to remember
- // the color cursor being set. Installed as a "Head" patch, meaning the original
- // SetCCursor trap is called after this code has completed.
- //----------------------------------------------------------------------------------------
- #pragma segment MABusyCursorRes
-
- pascal void TBusyCursor::SetCMacAppCursorPatch(CCrsrHandle theCCursor)
- {
- long OldA5 = SetCurrentA5(); // ***** Called from trap patches *****
-
- if (fgBusyCursor)
- fgBusyCursor->SetCMacAppCursor(theCCursor);
-
- pSCCPatch.CallInherited(theCCursor);
-
- SetA5(OldA5);
- } // SetCMacAppCursorPatch
-
- #pragma segment MABusyCursorRes
-
- pascal void TBusyCursor::SetMacAppCursorPatch(const Cursor* theCursor)
- {
- long OldA5 = SetCurrentA5(); // ***** Called from trap patches *****
-
- if (fgBusyCursor)
- fgBusyCursor->SetMacAppCursor(theCursor);
-
- pSCPatch.CallInherited(theCursor);
-
- SetA5(OldA5);
- } // SetMacAppCursorPatch
-
- //----------------------------------------------------------------------------------------
- // InitUBusyCursor:
- //----------------------------------------------------------------------------------------
- #pragma segment MAInit
-
- void TBusyCursor::InitUBusyCursor()
- {
- TBusyCursor* aBusyCursor = new TBusyCursor; // Create the BusyCursor mechanism
- aBusyCursor->IBusyCursor(); // Automatically sets fgBusyCursor
- fgBusyCursor = aBusyCursor;
- } // InitUBusyCursor
-
-
- //----------------------------------------------------------------------------------------
- // TerminateUBusyCursor:
- //----------------------------------------------------------------------------------------
- #pragma segment MABusyCursorRes
-
- void TBusyCursor::TerminateUBusyCursor()
- {
- gBusyCursor = (TBusyCursor *)FreeIfObject(gBusyCursor);
- } // TerminateUBusyCursor
-
-
- //----------------------------------------------------------------------------------------
- // InitMacAppCursor: Called when the InitCursor trap is executed. After completion, we
- // jump to the ROM InitCursor.
- //----------------------------------------------------------------------------------------
- #pragma segment MABusyCursorRes
-
- pascal void TBusyCursor::InitMacAppCursor()
- {
- long OldA5 = SetCurrentA5(); // ***** Called from trap patches *****
-
- if (fgBusyCursor)
- fgBusyCursor->SetMacAppCursor(&qd.arrow);
-
- pICPatch.CallInherited();
-
- SetA5(OldA5);
- } // InitMacAppCursor
-
- //----------------------------------------------------------------------------------------
- // NextAnimatedCursor:
- //----------------------------------------------------------------------------------------
- #pragma segment MABusyCursorRes
-
- CursHandle TBusyCursor::NextAnimatedCursor(AcurRsrcHandle acurRsrc)
- {
- AcurRsrcRecord& whichAcurRsrc = **acurRsrc; // OK: it's locked down in InitializeAnimatedCursor
-
- if (++whichAcurRsrc.whichCursor >= whichAcurRsrc.noOfCursors)
- whichAcurRsrc.whichCursor = 0;
-
- return whichAcurRsrc.cursors[whichAcurRsrc.whichCursor].Memory.h;
- } // NextAnimatedCursor
-
- //----------------------------------------------------------------------------------------
- // ABusyTask:
- //----------------------------------------------------------------------------------------
- #pragma segment MABusyCursorRes
-
- pascal void ABusyTask(
- #if qPowerPC
- VBLTaskPtr vblTaskPtr
- #endif
- )
- {
- // if we are running native PowerPC, the runtime architecture passes us a pointer to our
- // VBLTask as a parameter… othewise we have to retrieve it.
- #if !qPowerPC
- VBLTaskPtr vblTaskPtr = (VBLTaskPtr)GetParmBlockPtr();
- #endif
-
- TBusyCursor* theBusyCursor = ((QElemWithBusyCursor*)vblTaskPtr)->fBusyCursor;
- if (theBusyCursor)
- {
- long OldA5 = SetA5(theBusyCursor->fA5);
-
- theBusyCursor->BusyTask();
-
- SetA5(OldA5);
- }
- } // ABusyTask
-
-
- //========================================================================================
- // CLASS TBusyCursor
- //========================================================================================
- #undef Inherited
- #define Inherited TObject
-
- #pragma segment MAInit
- MA_DEFINE_CLASS_M1(TBusyCursor, Inherited);
-
- //----------------------------------------------------------------------------------------
- // TBusyCursor::TBusyCursor
- //----------------------------------------------------------------------------------------
- #pragma segment ConstructorRes
-
- TBusyCursor::TBusyCursor()
- {
- fInColor = FALSE;
- fOrigCCursor = NULL;
- fBusyDelay = 0;
- fInControl = FALSE;
- fChangeToBusy = FALSE;
- fIgnoreReset = FALSE;
- fBusyOn = FALSE;
- fCursorState = NULL;
- fAnimateDelay = 0;
- fTimeoutCount = 0;
- fSpinCount = 0;
- } // TBusyCursor::TBusyCursor
-
- //----------------------------------------------------------------------------------------
- // TBusyCursor::IBusyCursor:
- //----------------------------------------------------------------------------------------
- #pragma segment MAInit
-
- void TBusyCursor::IBusyCursor()
- {
- this->IObject();
-
- FailInfo fi;
- Try(fi)
- {
- // Setup the pCursorInfo record
- fInControl = TRUE; // we are in control during initialization
- fOrigCursor = qd.arrow;
- fBusyDelay = kBusyDelay;
- fInColor = FALSE;
- fChangeToBusy = TRUE;
- fBusyOn = FALSE;
-
- fA5 = SetCurrentA5(); // make the A5 world available to the VBL task
- // note: this was previously done with GetA5, but it
- // should be safe for us to use the PowerPC-compatible
- // SetCurrentA5 instead at this point…
-
- this->SetAnimatedCursor(kAcurRsrcID, kAnimateDelay);// init the animated cursor routine
- this->SetTimeout(kTicksBeforeTimeout); // NOTE: needs fAnimateDelay
-
- // Setup the VBL task
- fQElemWithBusyCursor.q.qType = vType;
- FailNIL(fQElemWithBusyCursor.q.vblAddr = NewVBLProc(StripLong(ABusyTask)));
- fQElemWithBusyCursor.q.vblCount = kBusyDelay;
- fQElemWithBusyCursor.q.vblPhase = 0;
- fQElemWithBusyCursor.fBusyCursor = this;
-
- // Patch the necessary traps
- pSCPatch.Install(SetMacAppCursorPatch);
- pICPatch.Install(InitMacAppCursor);
- if (qNeedsColorQD || HasColorQD())
- pSCCPatch.Install(SetCMacAppCursorPatch);
-
- // Install the VBL task
- FailOSErr(VInstall((QElemPtr) & fQElemWithBusyCursor.q));
- pBusyCursorVBLInstalled = TRUE;
-
- // Patch the traps applicable
- pGNEPatch.Install(ResetBusyGetNextEvent);
- pSDPatch.Install(ResetBusyStillDown);
- #if qPatchEventAvail
- pEAPatch.Install(ResetBusyEventAvail);
- #endif
- if (HasAUX())
- pWMUPatch.Install(ResetBusyWaitMouseUp);
-
- // Set busy delay
- this->SetDelay(kBusyDelay);
-
- fi.Success();
- }
- else
- {
- this->Free();
- fi.ReSignal();
- }
- } // TBusyCursor::IBusyCursor
-
- //----------------------------------------------------------------------------------------
- // TBusyCursor::Free:
- //----------------------------------------------------------------------------------------
- #pragma segment MATerminate
-
- TBusyCursor::~TBusyCursor()
- {
- this->Reset(1); // Restore the non-busy cursor
-
- if (pBusyCursorVBLInstalled)
- VRemove((QElemPtr) & fQElemWithBusyCursor.q); // Remove the VBL task
-
- this->ReleaseAnimatedCursor();
-
- // Unpatch the patches
- pICPatch.UnpatchTrap();
- pSCPatch.UnpatchTrap();
- if (qNeedsColorQD || HasColorQD())
- pSCCPatch.UnpatchTrap();
-
- pGNEPatch.UnpatchTrap();
- pSDPatch.UnpatchTrap();
- #if qPatchEventAvail
- pEAPatch.UnpatchTrap();
- #endif
- if (HasAUX())
- pWMUPatch.UnpatchTrap();
- } // TBusyCursor::Free
-
- //----------------------------------------------------------------------------------------
- // TBusyCursor::Reset:
- //----------------------------------------------------------------------------------------
- #pragma segment MABusyCursorRes
-
- void TBusyCursor::Reset(short delayTicks)
- {
- if (fInControl && fChangeToBusy)
- {
- if (fBusyOn)
- if (fInColor)
- SetCCursor(fOrigCCursor);
- else
- SetCursor(&(fOrigCursor));
- fQElemWithBusyCursor.q.vblCount = delayTicks;
- }
- } // TBusyCursor::Reset
-
- //----------------------------------------------------------------------------------------
- // TBusyCursor::Activate:
- //----------------------------------------------------------------------------------------
- #pragma segment MABusyCursorRes
-
- Boolean TBusyCursor::Activate(Boolean entering)
- {
- return this->InControl(entering, TRUE);
- } // TBusyCursor::Activate
-
- //----------------------------------------------------------------------------------------
- // TBusyCursor::InControl:
- //----------------------------------------------------------------------------------------
- #pragma segment MABusyCursorRes
-
- Boolean TBusyCursor::InControl(Boolean entering, Boolean reset)
- {
- if (reset)
- this->Reset(fBusyDelay);
-
- Boolean returnVal = fInControl;
- fInControl = entering;
-
- return returnVal;
- } // TBusyCursor::InControl
-
- //----------------------------------------------------------------------------------------
- // TBusyCursor::SetDelay:
- //----------------------------------------------------------------------------------------
- #pragma segment MABusyCursorRes
-
- void TBusyCursor::SetDelay(short newDelay)
- {
- if (newDelay > 0) // save new delay time
- {
- fBusyDelay = newDelay;
- this->Reset(newDelay); // reset timer
- }
- } // TBusyCursor::SetDelay
-
- //----------------------------------------------------------------------------------------
- // TBusyCursor::ForceBusy: Trigger on next tick and reset timer
- //----------------------------------------------------------------------------------------
- #pragma segment MABusyCursorRes
-
- void TBusyCursor::ForceBusy()
- {
- this->Reset(1);
- } // TBusyCursor::ForceBusy
-
- //----------------------------------------------------------------------------------------
- // TBusyCursor::TurnOff: This is called from InitMacAppCursor, SetMacAppCursor and
- // SetCMacAppCursor. It sets pCursorInfo fields to indicate that the cursor is not the
- // busy cursor.
- //----------------------------------------------------------------------------------------
- #pragma segment MABusyCursorRes
-
- void TBusyCursor::TurnOff()
- {
- if (fInControl && fChangeToBusy)
- {
- fBusyOn = FALSE; // anyone that sets the busy cursor should set this true explicitly
- fQElemWithBusyCursor.q.vblCount = fBusyDelay;
- }
- } // TBusyCursor::TurnOff
-
- //----------------------------------------------------------------------------------------
- // TBusyCursor::InitializeAnimatedCursor:
- //----------------------------------------------------------------------------------------
- #pragma segment MAInit
-
- AcurRsrcHandle TBusyCursor::InitializeAnimatedCursor(ResNumber acurRsrcId)
- {
- ReserveMem(sizeof(AcurRsrcRecord)); // so it will load low
- AcurRsrcHandle acurRsrc = (AcurRsrcHandle)GetResource('acur', acurRsrcId);
-
- if (acurRsrc)
- {
- DetachResource((Handle)acurRsrc); // cause we do bookkeeping in it. Don't want to dirty orig.
- HNoPurge((Handle)acurRsrc);
- HLock((Handle)acurRsrc);
- (*acurRsrc)->whichCursor = 0;
-
- // Load each cursor in the sequence and lock them in memory
- for (short i = 0; i < (*acurRsrc)->noOfCursors; ++i)
- {
- ReserveMem(sizeof(Cursor)); // so it will load low
- CursHandle theCursor = GetCursor((*acurRsrc)->cursors[i].Disk.rsrcId);// Get the cursor from the disk
- FailNILResource((Handle)theCursor);
- (*acurRsrc)->cursors[i].Memory.h = theCursor; // remember the cursor
- HNoPurge((Handle)theCursor);
- HLock((Handle)theCursor); // Make sure it is locked
- }
- }
-
- return acurRsrc;
- } // TBusyCursor::InitializeAnimatedCursor
-
- //----------------------------------------------------------------------------------------
- // TBusyCursor::Animate:
- //----------------------------------------------------------------------------------------
- #pragma segment MABusyCursorRes
-
- void TBusyCursor::Animate()
- {
- fSpinCount = 0; // zero spins since we last heard from the app
- } // TBusyCursor::Animate
-
- //----------------------------------------------------------------------------------------
- // TBusyCursor::SetTimeout:
- //----------------------------------------------------------------------------------------
- #pragma segment MABusyCursorRes
-
- void TBusyCursor::SetTimeout(long ticksBeforeTimeout)
- {
- fTimeoutCount = ticksBeforeTimeout / fAnimateDelay;
- fSpinCount = 0;
- } // TBusyCursor::SetTimeout
-
- //----------------------------------------------------------------------------------------
- // TBusyCursor::KeepCursorBusy:
- //----------------------------------------------------------------------------------------
- #pragma segment MABusyCursorRes
-
- Boolean TBusyCursor::KeepCursorBusy(Boolean keepItSpinning)
- {
- Boolean currentSetting = fIgnoreReset;
- fIgnoreReset = keepItSpinning;
- return currentSetting;
- }
-
- //----------------------------------------------------------------------------------------
- // TBusyCursor::SetAnimatedCursor:
- //----------------------------------------------------------------------------------------
- #pragma segment MABusyCursorRes
-
- void TBusyCursor::SetAnimatedCursor(ResNumber itsACUR, short animateDelay)
- {
- Boolean wasInControl = fInControl;
- fInControl = FALSE; // so the vbl doesn't whack us!
-
- this->ReleaseAnimatedCursor();
-
- fCursorState = this->InitializeAnimatedCursor(itsACUR);// init the animated cursor routine
- if (fCursorState)
- fCurrentCursor = **NextAnimatedCursor(fCursorState);// get the first cursor
- else
- fCurrentCursor = **GetCursor(watchCursor);
-
- fAnimateDelay = animateDelay;
-
- fInControl = wasInControl;
- }
-
-
- //----------------------------------------------------------------------------------------
- // TBusyCursor::ReleaseAnimatedCursor:
- //----------------------------------------------------------------------------------------
- #pragma segment MABusyCursorRes
-
- void TBusyCursor::ReleaseAnimatedCursor()
- {
- if (fCursorState)
- {
- for (short i = 0; i < (*fCursorState)->noOfCursors; ++i)
- ReleaseResource((Handle)(*fCursorState)->cursors[i].Memory.h);
- fCursorState = (AcurRsrcHandle)DisposeIfHandle((Handle)fCursorState);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // SetMacAppCursor: Must be in Main segment, and cannot call to any other segment because
- // SetCursor is called from the ABusyTask VBL task. Patches SetCursor to remember the
- // cursor being set. Installed as a "Head" patch, meaning the original SetCursor trap is
- // called after this code has completed. Also called from InitMacAppCursor.
- //----------------------------------------------------------------------------------------
- #pragma segment MABusyCursorRes
-
- void TBusyCursor::SetMacAppCursor(const Cursor* theCursor)
- {
- this->TurnOff();
-
- // If we are setting the cursor to the busy cursor, then don't save it
- if (theCursor != &fCurrentCursor)
- {
- fInColor = FALSE;
- fOrigCursor = *theCursor;
- }
- else
- fBusyOn = TRUE; // because BusyTurnOff set it to false
- } // SetMacAppCursor
-
- //----------------------------------------------------------------------------------------
- // SetCMacAppCursor: Must be in Main segment, and cannot call to any other segment because
- // SetCursor is called from the ABusyTask VBL task. The SetCCursor patch, used to remember
- // the color cursor being set. Installed as a "Head" patch, meaning the original
- // SetCCursor trap is called after this code has completed.
- //----------------------------------------------------------------------------------------
- #pragma segment MABusyCursorRes
-
- void TBusyCursor::SetCMacAppCursor(CCrsrHandle theCCursor)
- {
- this->TurnOff();
-
- fInColor = TRUE;
- fOrigCCursor = theCCursor; // Save a copy of the color cursor
- } // SetCMacAppCursor
-
- //----------------------------------------------------------------------------------------
- // TBusyCursor::BusyTask
- //----------------------------------------------------------------------------------------
- #pragma segment MABusyCursorRes
-
- void TBusyCursor::BusyTask()
- {
- // always Reset the vblCount
- fQElemWithBusyCursor.q.vblCount = fBusyDelay;
-
- if (!LMGetCrsrBusy() && fInControl && fChangeToBusy)
- if (fCursorState) // if we have an animated cursor
- {
- if (!fBusyOn)
- fSpinCount = 0;
- if (fSpinCount <= fTimeoutCount)
- {
- fCurrentCursor = **NextAnimatedCursor(fCursorState);
- SetCursor(&fCurrentCursor);
- ++fSpinCount;
- }
- fQElemWithBusyCursor.q.vblCount = fAnimateDelay;
- }
- else if (!fBusyOn)
- SetCursor(&fCurrentCursor);
-
- } // BusyTask
-
-
- //----------------------------------------------------------------------------------------
- // End of UBusyCursor.cp
-
- #pragma segment Inline
-